﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenerateurMusique
{
    class Population
    {
        /// <summary>
        /// Création de la liste d'individus
        /// </summary>
        public Individu[] tabIndividus = new Individu[10];
        public Individu[] tabEnfants = new Individu[10];
        public List<Individu> tabReproducteur = new List<Individu>();
        /// <summary>
        /// Constantes d'évolution
        /// </summary>
        //public Double tauxMutation = 1.2;
        public Double tauxCrossover = 0.6;
        
        /// <summary>
        /// Compteur de générations
        /// </summary>
        public int countGen = 0;

        public int nbTickets = 0;
        public int ticketsTotaux = 0;

        /// <summary>
        /// Méthode d'initialisation de la population = constructeur
        /// </summary>
        public Population()
        {
            for (int i = 0; i < 10; i++)
            {
                this.tabIndividus[i] = new Individu();
                System.Threading.Thread.Sleep(50);
            }
        }

        /// <summary>
        /// Select the reproduct (Method : biased roulette wheel)
        /// </summary>
        public void selectionReproducteur()
        {
            //Obtention du nombre de tickets totaux
            for (int i = 0; i < 10; i++)
            {
                ticketsTotaux = ticketsTotaux + tabIndividus[i].getTickets();
            }

            //Roulette Biaisée avec rang
            for (int i = 0; i < 10; i++)
            {
                Random rand = new Random();
                int enfant = rand.Next(0, ticketsTotaux);
                //comparaison entre le rand et la tranche qui est entre nbtickets de celui d'avant et son nombre de tickets + celui de l'ancien
                if (enfant > 0 && enfant < (tabIndividus[0].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[0]);
                }
                else if (enfant >= (tabIndividus[0].getTickets()) && enfant < (tabIndividus[0].getTickets() + tabIndividus[1].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[1]);
                }
                else if (enfant >= (tabIndividus[0].getTickets() + tabIndividus[1].getTickets()) && enfant < (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[2]);
                }
                else if (enfant >= (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets()) && enfant < (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[3]);
                }
                else if (enfant >= (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets()) && enfant < (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[4]);
                }
                else if (enfant >= (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets()) && enfant < (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets() + tabIndividus[5].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[5]);
                }
                else if (enfant >= (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets() + tabIndividus[5].getTickets()) && enfant < (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets() + tabIndividus[5].getTickets() + tabIndividus[6].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[6]);
                }
                else if (enfant >= (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets() + tabIndividus[5].getTickets() + tabIndividus[6].getTickets()) && enfant < (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets() + tabIndividus[5].getTickets() + tabIndividus[6].getTickets() + tabIndividus[7].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[7]);
                }
                else if (enfant >= (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets() + tabIndividus[5].getTickets() + tabIndividus[6].getTickets() + tabIndividus[7].getTickets()) && enfant < (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets() + tabIndividus[5].getTickets() + tabIndividus[6].getTickets() + tabIndividus[7].getTickets() + tabIndividus[8].getTickets()))
                {
                    tabReproducteur.Add(tabIndividus[8]);
                }
                else if (enfant >= (tabIndividus[0].getTickets() + tabIndividus[1].getTickets() + tabIndividus[2].getTickets() + tabIndividus[3].getTickets() + tabIndividus[4].getTickets() + tabIndividus[5].getTickets() + tabIndividus[6].getTickets() + tabIndividus[7].getTickets() + tabIndividus[8].getTickets()) && enfant < ticketsTotaux)
                {
                    tabReproducteur.Add(tabIndividus[9]);
                }
                System.Threading.Thread.Sleep(50);
            }
            return;
        }

        /// <summary>
        /// Make the reproduction with random (for One or Two Parents)
        /// </summary>
        public void reproduction()
        {
            for (int i = 0; i < 10; i++)
            {
                if (tabReproducteur.Count >= 2)
                {
                    Random rand = new Random();
                    int random = rand.Next(0, 1);
                    int parent1 = rand.Next(0, this.tabReproducteur.Count - 1);
                    if (random == 0)
                    {
                        tabEnfants[i] = new Individu(tabReproducteur[parent1]);
                        tabReproducteur.Remove(tabReproducteur[parent1]);
                    }
                    else if (random == 1)
                    {
                        Individu reproducteur1 = tabReproducteur[parent1];
                        tabReproducteur.Remove(tabReproducteur[parent1]);
                        int parent2 = rand.Next(0, this.tabReproducteur.Count - 1);
                        tabEnfants[i] = new Individu(reproducteur1, tabReproducteur[parent2]);
                        tabReproducteur.Remove(tabReproducteur[parent2]);
                    }
                }
                else
                {
                    tabEnfants[i] = new Individu(tabReproducteur[0]);
                    tabReproducteur.Remove(tabReproducteur[0]);
                }
                System.Threading.Thread.Sleep(50);
            }
        }

        /// <summary>
        /// Make the survival of the population (Method : Elitisme)
        /// </summary>
        public void individuSurvie()
        {
            // méthode déterministe : on remplace tous les parents par les enfants
            for (int i = 0; i < 10; i++){
                tabIndividus[i] = tabEnfants[i];
            }
            
            //Incrémentation de la génération
            countGen++;
        }
    }
}
